package com.zhou.bjgl.bjgl.business_web.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.zhou.bjgl.bjgl.business_web.entity.*;
import com.zhou.bjgl.bjgl.exception.BwException;
import com.zhou.bjgl.bjgl.exception.BwExceptionEnum;
import com.zhou.bjgl.bjgl.business_web.mapper.*;
import com.zhou.bjgl.bjgl.req.BaseModel;
import com.zhou.bjgl.bjgl.req.b_student.BStudentQueryReq;
import com.zhou.bjgl.bjgl.req.b_teacher.BTeacherQueryReq;
import com.zhou.bjgl.bjgl.req.user.UserEditPasswordReq;
import com.zhou.bjgl.bjgl.req.user.UserReq;
import com.zhou.bjgl.bjgl.resp.*;
import com.zhou.bjgl.bjgl.resp.student.BStudentQueryResp;
import com.zhou.bjgl.bjgl.resp.teacher.BTeacherResp;
import com.zhou.bjgl.bjgl.resp.user.BUserForInfoResp;
import com.zhou.bjgl.bjgl.resp.user.BUserForQueryResp;
import com.zhou.bjgl.bjgl.business_web.service.CommonService;
import com.zhou.bjgl.bjgl.util.CopyUtil;
import com.zhou.bjgl.bjgl.util.GetFileMsg;
import com.zhou.bjgl.bjgl.util.MinioUtil;
import com.zhou.bjgl.bjgl.util.RedisUtil;
import com.zhou.bjgl.bjgl.util.coder.SHA256Encrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import static com.zhou.bjgl.bjgl.util.WechatUtil.getAccessToken;


/**
 * @ClassName: 公共servcie实现类
 * @Description:
 * @Author: admin
 * @Date: 2021/7/4 14:41
 */
@Service
public class CommonServiceImpl extends BaseModel implements CommonService {


    private static final String PROFILE_FOLDER = "http://122.112.201.131:9000/myprofile/";

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Resource
    private BStudentMapper bStudentMapper;

    @Resource
    private BTeacherMapper bTeacherMapper;

    @Resource
    private BClassMapper bClassMapper;

    @Resource
    private BCollegeMapper bCollegeMapper;

    @Resource
    private BRoleMapper bRoleMapper;

    @Resource
    private RedisUtil redisUtil;

    @Autowired
    private MinioUtil minioUtil;

    /**
     * 用于用户登录，用户来自教师表和学生表。数据表设计不太正确，不应该把学生和教师分开，以后进行修改
     *
     * @param req
     * @return
     */
    @Override
    public BUserForQueryResp login(UserReq req) {

        req.setPassword(SHA256Encrypt.getSHA256StrJava(req.getPassword()));
        //教师实体
        BTeacherQueryReq bTeacherQueryReq = new BTeacherQueryReq();
        bTeacherQueryReq.setUsername(req.getUsername());
        bTeacherQueryReq.setPassword(req.getPassword());
        //学生实体
        BStudentQueryReq bStudentQueryReq = new BStudentQueryReq();
        bStudentQueryReq.setUsername(req.getUsername());
        bStudentQueryReq.setPassword(req.getPassword());


        //查询学生
        BStudentQueryResp studentResp = bStudentMapper.queryStuInfo(bStudentQueryReq);

        //如果学生表有数据
        if (studentResp != null) {
            if (studentResp.getClassName() == null) {
                studentResp.setClassName("未分配");
            }
            return CopyUtil.copy(studentResp, BUserForQueryResp.class);
        }

        //查询教师
        BTeacherResp teacherResp = bTeacherMapper.queryTeaInfo(bTeacherQueryReq);

        //如果教师表和学生表都不存在，则登录失败
        if (teacherResp == null) {
            throw new BwException(BwExceptionEnum.LOGIN_FAIL);
        }

        if (teacherResp.getClassName() == null) {
            teacherResp.setClassName("未分配");
        }
        BUserForQueryResp userResult = CopyUtil.copy(teacherResp, BUserForQueryResp.class);
        return userResult;

    }

    /**
     * 用于获取用户信息
     *
     * @param req
     * @return
     */
    @Override
    public BUserForInfoResp getUserInfo(UserReq req) {

        //教师实体
        BTeacherQueryReq bTeacherQueryReq = new BTeacherQueryReq();
        bTeacherQueryReq.setUsername(req.getUsername());
        bTeacherQueryReq.setPassword(req.getPassword());
        //学生实体
        BStudentQueryReq bStudentQueryReq = new BStudentQueryReq();
        bStudentQueryReq.setUsername(req.getUsername());
        bStudentQueryReq.setPassword(req.getPassword());


        //查询学生
        BStudentQueryResp studentResp = bStudentMapper.queryStuInfo(bStudentQueryReq);

        //如果学生表有数据
        if (studentResp != null) {
            if (studentResp.getClassName() == null) {
                studentResp.setClassName("未分配");
            }
            return CopyUtil.copy(studentResp, BUserForInfoResp.class);
        }

        //查询教师
        BTeacherResp teacherResp = bTeacherMapper.queryTeaInfo(bTeacherQueryReq);

        //如果教师表和学生表都不存在，则登录失败
        if (teacherResp == null) {
            throw new BwException(BwExceptionEnum.LOGIN_FAIL);
        }

        if (teacherResp.getClassName() == null) {
            teacherResp.setClassName("未分配");
        }
        BUserForInfoResp userResult = CopyUtil.copy(teacherResp, BUserForInfoResp.class);
        return userResult;

    }

    /**
     * 用于获取用户信息
     *
     * @param req
     * @return
     */
    @Override
    public BUserForInfoResp getUserInfoForEdit(UserReq req) {

        //教师实体
        BTeacherQueryReq bTeacherQueryReq = new BTeacherQueryReq();
        bTeacherQueryReq.setUsername(req.getUsername());
        bTeacherQueryReq.setPassword(req.getPassword());
        //学生实体
        BStudentQueryReq bStudentQueryReq = new BStudentQueryReq();
        bStudentQueryReq.setUsername(req.getUsername());
        bStudentQueryReq.setPassword(req.getPassword());


        //查询学生
        BStudentQueryResp studentResp = bStudentMapper.queryStuInfo(bStudentQueryReq);

        //如果学生表有数据
        if (studentResp != null) {
            return CopyUtil.copy(studentResp, BUserForInfoResp.class);
        }

        //查询教师
        BTeacherResp teacherResp = bTeacherMapper.queryTeaInfo(bTeacherQueryReq);

        //如果教师表有数据
        if (teacherResp != null) {
            BUserForInfoResp userResult = CopyUtil.copy(teacherResp, BUserForInfoResp.class);
            return  userResult;
        }

        return null;

    }

    /**
     * 获取班级多级列表数据
     *
     * @param collegeId
     * @return
     */
    @Override
    public List<BClassResp> getClassdata(Long collegeId) {
        QueryWrapper<BClass> bClassQueryWrapper = new QueryWrapper<>();
        bClassQueryWrapper.eq("college_id", collegeId);
        //从数据库中获取数据
        List<BClass> bClasses = bClassMapper.selectList(bClassQueryWrapper);
        List<BClassResp> bClassResps = CopyUtil.copyList(bClasses, BClassResp.class);
        return bClassResps;

    }

    /**
     * 获取学院班级列表数据
     *
     * @param parentId
     * @return
     */
    @Override
    public List<BCollegeResp> getCollegedata(Long parentId) {

        String collegeList = (String) redisUtil.get("collegeList");
        if (collegeList == null) {
            QueryWrapper<BCollege> bCollegeQueryWrapper = new QueryWrapper<>();
            bCollegeQueryWrapper.eq("parent_id", parentId);
            //从数据库中获取数据
            List<BCollege> bColleges = bCollegeMapper.selectList(bCollegeQueryWrapper);
            List<BCollegeResp> bCollegeResps = CopyUtil.copyList(bColleges, BCollegeResp.class);
            //将list转为json字符串方便在redis中存储
            JSONArray jsonArray = JSONObject.parseArray(JSONObject.toJSONString(bCollegeResps));
            String bCollegeRespsString = jsonArray.toString();
            redisUtil.set("collegeList", bCollegeRespsString);
            return bCollegeResps;
        } else {
            //把获取到的string数据转化为list
            List<BCollegeResp> bCollegeRespsInReids = JSONObject.parseObject(collegeList, new TypeReference<List<BCollegeResp>>() {
            });
            return bCollegeRespsInReids;
        }


    }

    /**
     * 获取权限多级类别数据
     *
     * @return
     */
    @Override
    public List<BRoleResp> getRoleData() {
        QueryWrapper<BRole> bRoleQueryWrapper = new QueryWrapper<>();
        bRoleQueryWrapper.eq("del_status", 0);
        List<BRole> bRoles = bRoleMapper.selectList(bRoleQueryWrapper);
        List<BRoleResp> bRoleResps = CopyUtil.copyList(bRoles, BRoleResp.class);
        return bRoleResps;
    }

    /**
     * 检查用户是否存在
     *
     * @param req
     */
    @Override
    public void UserIsExist(UserReq req) {
        BTeacherQueryReq bTeacherQueryReq = new BTeacherQueryReq();
        bTeacherQueryReq.setUsername(req.getUsername());
        BStudentQueryReq bStudentQueryReq = new BStudentQueryReq();
        bStudentQueryReq.setUsername(req.getUsername());
        List<BTeacherResp> teacherResps = bTeacherMapper.queryTea(bTeacherQueryReq);
        List<BStudentQueryResp> bStudentQueryResps = bStudentMapper.queryStu(bStudentQueryReq);
        //如果教师表和学生表都不存在，则登录失败
        if (teacherResps.size() == 0 && bStudentQueryResps.size() == 0) {
            throw new BwException(BwExceptionEnum.USER_NOT_EXIST);
        }
    }


    /**
     * 用于给用户发送微信订阅信息
     *
     * @param activityName
     * @param appid
     */
    @Override
    public void pushNoticeUtil(String activityName, String appid) {
        String format = sdf.format(new Date());
        JSONObject body = new JSONObject();
        body.put("touser", appid);
        body.put("template_id", "PbWKlH5fLtxI1cQBzXPfbPibJz7PrKILsPaUYZYppPI");
//        body.put("page", "pages/mine/mine");
        JSONObject json = new JSONObject();
        JSONObject jsonObject1 = new JSONObject();
        JSONObject jsonObject2 = new JSONObject();
        JSONObject jsonObject3 = new JSONObject();
        jsonObject1.put("value", activityName);
        jsonObject2.put("value", format);
        jsonObject3.put("value", "您发起的签到已结束");
        json.put("thing1", jsonObject1);
        json.put("time2", jsonObject2);
        json.put("thing4", jsonObject3);
        body.put("data", json);
        //发送
        String accessToken = getAccessToken().get("access_token").toString();
        String post = cn.hutool.http.HttpUtil.post("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken, body.toString());

    }

    @Override
    public void changePassword(UserEditPasswordReq userEditPasswordReq) {
        //查询原来的密码是否正确
        //通过ThradLocal获取用户id
        Long id = threadLocal.get().getId();

        //如果是学生
        if (threadLocal.get().getPower() >= 2) {
            BStudent bStudent = bStudentMapper.selectById(id);
            if (ObjectUtils.nullSafeEquals(bStudent.getPassword(), SHA256Encrypt.getSHA256StrJava(userEditPasswordReq.getOldPassword()))) {
                BStudent bStudentNew = new BStudent();
                bStudentNew.setPassword(SHA256Encrypt.getSHA256StrJava(userEditPasswordReq.getNewPassword()));
                bStudentNew.setId(id);
                bStudentMapper.update(bStudent,new QueryWrapper<BStudent>().eq("id",id));
            } else {
                //如果旧密码不正确
                throw new BwException(BwExceptionEnum.OLD_PASSWORD_EORRO);
            }
        } else {
            //如果是老师
            BTeacher bTeacher = bTeacherMapper.selectById(id);
            if (ObjectUtils.nullSafeEquals(bTeacher.getPassword(), SHA256Encrypt.getSHA256StrJava(userEditPasswordReq.getOldPassword()))) {
                BTeacher bTeacherNew = new BTeacher();
                bTeacherNew.setPassword(SHA256Encrypt.getSHA256StrJava(userEditPasswordReq.getNewPassword()));
                bTeacherNew.setId(id);
                bTeacherNew.setClassId(threadLocal.get().getClassId());
                bTeacherMapper.update(bTeacherNew,new QueryWrapper<BTeacher>().eq("id",id));
            } else {
                //如果旧密码不正确
                throw new BwException(BwExceptionEnum.OLD_PASSWORD_EORRO);
            }
        }
        redisUtil.del(threadLocal.get().getUsername());
    }

    @Override
    public String uploadProfile(MultipartFile profile) {
        //新文件名
        String filnameNew = UUID.randomUUID()+".png";
        BUserForInfoResp bUserForInfoResp = threadLocal.get();
        //进行文件上传
        minioUtil.uploadFile(profile, filnameNew);
        //进行文件信息入库
        String profileName = filnameNew;
        String profileUrl = PROFILE_FOLDER + filnameNew;
        Integer power = bUserForInfoResp.getPower();
        Long id = bUserForInfoResp.getId();
        //进行信息更新
        if (power >= 3) {
            BStudent bStudent = new BStudent();
            bStudent.setProfileUrl(profileUrl);
            bStudent.setProfileName(profileName);
            bStudent.setId(id);
            bStudentMapper.updateById(bStudent);
        } else {
            BTeacher bTeacher = new BTeacher();
            bTeacher.setProfileName(profileName);
            bTeacher.setProfileUrl(profileUrl);
            bTeacher.setId(id);
            bTeacherMapper.updateById(bTeacher);
        }
        redisUtil.del(threadLocal.get().getUsername());
        //返回minio中的文件预览地址
        return profileUrl;
    }

    @Override
    public void changeUserInfo(UserReq userReq) {
        BUserForInfoResp bUserForInfoResp = threadLocal.get();
        Integer power = bUserForInfoResp.getPower();
        Long id = bUserForInfoResp.getId();
        //进行信息更新
        if (power >= 3) {
            BStudent bStudent = new BStudent();
            bStudent.setPhone(userReq.getPhone());
            bStudent.setEmail(userReq.getEmail());
            bStudent.setId(id);
            bStudentMapper.updateById(bStudent);
        } else {
            BTeacher bTeacher = new BTeacher();
            bTeacher.setPhone(userReq.getPhone());
            bTeacher.setEmail(userReq.getEmail());
            bTeacher.setId(id);
            bTeacherMapper.updateById(bTeacher);
        }
        redisUtil.del(threadLocal.get().getUsername());
    }
}
